package com.xc.hotelmgr.order.modules.mt.service;

import com.alibaba.fastjson.JSONObject;
import com.xc.hotelmgr.order.common.utils.Constant;
import com.xc.hotelmgr.order.common.utils.DateUtils;
import com.xc.hotelmgr.order.common.utils.R;
import com.xc.hotelmgr.order.common.utils.XmlUtils;
import com.xc.hotelmgr.order.modules.ali.to.bookrq.request.BookRQ;
import com.xc.hotelmgr.order.modules.ali.to.bookrq.request.OrderGuest;
import com.xc.hotelmgr.order.modules.ali.to.bookrq.response.BookRQResult;
import com.xc.hotelmgr.order.modules.ali.to.cancelrq.CancelRQResult;
import com.xc.hotelmgr.order.modules.ali.to.manuorder.Dailyroom;
import com.xc.hotelmgr.order.modules.ali.to.manuorder.ManuBookRQ;
import com.xc.hotelmgr.order.modules.mt.sdk.FxBaseApiRequest;
import com.xc.hotelmgr.order.modules.mt.sdk.MtClient;
import com.xc.hotelmgr.order.modules.mt.to.booking.request.MtBook;
import com.xc.hotelmgr.order.modules.mt.to.booking.response.MtBookResult;
import com.xc.hotelmgr.order.modules.mt.to.cancel.CancelRequest;
import com.xc.hotelmgr.order.modules.mt.to.cancel.CancelResponse;
import com.xc.hotelmgr.order.modules.order.entity.DailyroomEntity;
import com.xc.hotelmgr.order.modules.order.entity.DtOrderChannelsEntity;
import com.xc.hotelmgr.order.modules.order.entity.OrderEntity;
import com.xc.hotelmgr.order.modules.order.service.DailyroomService;
import com.xc.hotelmgr.order.modules.order.service.DtOrderChannelsService;
import com.xc.hotelmgr.order.modules.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("mtHotelBooking")
@Slf4j
public class MtOrderService {
    @Autowired
    private DtOrderChannelsService dtOrderChannelsService;

    @Autowired
    private DailyroomService dailyroomService;

    @Autowired
    private OrderService orderService;
    /**
     * 预约下单(美团）
     * @param bookRQ
     * @return
     */
    public String booking(BookRQ bookRQ, Long ordId) {
        String userName = bookRQ.getAuthenticationToken().getUsername();
        DtOrderChannelsEntity dtOrderChannelsEntity = dtOrderChannelsService.sqlSelectKey(Constant.Channel.Mt.getValue(), userName);
        String accessKey = "";
        String secretKey = "";
        Integer partnerId = 0;
        Integer commRate = 0;
        if (dtOrderChannelsEntity != null) {
            accessKey = dtOrderChannelsEntity.getAccessKey();
            secretKey = dtOrderChannelsEntity.getSecretKey();
            partnerId = dtOrderChannelsEntity.getSid();
            commRate = dtOrderChannelsEntity.getCommRate();
        } else {
            log.error("美团：请配置飞猪接口用户名为{}的店铺对应的美团渠道账号", userName);
        }

        MtBook mtBook = new MtBook();
        mtBook.setHotelId(Long.valueOf(bookRQ.getHotelId()));
        mtBook.setGoodsId(Long.valueOf(bookRQ.getRatePlanCode()));
        String personNames = "";
        for (OrderGuest guest : bookRQ.getOrderGuests()) {
            personNames += guest.getName() + ",";
        }
        personNames = personNames.replaceAll("\\,$", "");
        mtBook.setPersonNames(personNames);
        mtBook.setContactName(bookRQ.getContactName());
        mtBook.setContactPhone(bookRQ.getContactTel());
        mtBook.setArriveDate(bookRQ.getLatestArriveTime());
        mtBook.setCheckinDate(bookRQ.getCheckIn());
        mtBook.setCheckoutDate(bookRQ.getCheckOut());
        mtBook.setRoomNum(Integer.valueOf(bookRQ.getRoomNum()));
        Integer totaolPrice = 0;
        Integer settlePrice = 0;
        //订单总价，单位为分。总价=预订房间数x预定日期内房间单价。
        // 例如，4月1日入住，4月3日离店，预定2间房，则总价=2*(4月1日房价+4月2日房价）
        List<DailyroomEntity> dailyroomEntities = dailyroomService.redisSelect(bookRQ.getRatePlanCode(), bookRQ.getCheckIn(), bookRQ.getCheckOut());
        for (DailyroomEntity d : dailyroomEntities) {
            totaolPrice += d.getPrice();
            settlePrice += d.getSubRatio() == null || d.getSubRatio() == 0 ? d.getPrice() * commRate : d.getPrice() * d.getSubRatio();
        }
        totaolPrice = totaolPrice * Integer.valueOf(bookRQ.getRoomNum());
        settlePrice = settlePrice * Integer.valueOf(bookRQ.getRoomNum()) / 1000;
        //结算价，单位为分。结算价=总价 - 分销商佣金。
        settlePrice = totaolPrice - settlePrice;
        mtBook.setTotalPrice(totaolPrice);
        mtBook.setSettlePrice(settlePrice);
        mtBook.setDistributorOrderId(bookRQ.getTaoBaoOrderId());
        if (StringUtils.isNotBlank(bookRQ.getComment())) {
            mtBook.setComment(bookRQ.getComment());
        }
        //设置发票信息，目前都是酒店前台开票,不需要美团开票
        mtBook.setNeedInvoice(0);

        FxBaseApiRequest fxBaseApiRequest = new FxBaseApiRequest();
        fxBaseApiRequest.setAccesskey(accessKey);
        fxBaseApiRequest.setSecretKey(secretKey);
        fxBaseApiRequest.setPartnerId(partnerId);
        fxBaseApiRequest.setData(JSONObject.toJSONString(mtBook));
        fxBaseApiRequest.setMethod("hotel.order.booking");

        //更新采购信息
        OrderEntity orderEntity = new OrderEntity();
        //构造返回
        BookRQResult bookRQResult = new BookRQResult();
        log.info("美团：预约下单，订单号：{},请求报文：{}", bookRQ.getTaoBaoOrderId(), fxBaseApiRequest.getData());
        String buyResult = "";
        try {
            buyResult = MtClient.post(fxBaseApiRequest);
        } catch (Exception ex) {
            orderEntity.setBuyStatus(0);
            orderEntity.setResultDesc(ex.toString().substring(0, 499));
            log.error("美团：订单号：{}，错误信息：{}", bookRQ.getTaoBaoOrderId(), ex.toString());
        }
        log.info("美团：预约下单，订单号：{},返回报文：{}", bookRQ.getTaoBaoOrderId(), buyResult);
        //返回给飞猪成功
        bookRQResult.setResultCode("0");
        bookRQResult.setMessage("创建订单成功");
        bookRQResult.setOrderId(ordId.toString());
        MtBookResult mtBookResult = JSONObject.parseObject(buyResult, MtBookResult.class);
        if (mtBookResult.getCode() == 0) {
            orderEntity.setBuyStatus(Constant.LocalOrdBuyStatus.Accepted.getValue());
            if (mtBookResult.getResult() != null && mtBookResult.getResult().getMtOrderId() != null) {
                orderEntity.setBuyOrderId(mtBookResult.getResult().getMtOrderId());
            }
        } else {
            orderEntity.setBuyStatus(Constant.LocalOrdBuyStatus.Purchfailure.getValue());
            log.error("美团：预约下单失败，订单号：{}，错误信息:{}",bookRQ.getTaoBaoOrderId(), mtBookResult.getMessage());
        }
        orderEntity.setId(ordId);
        orderEntity.setBuyOrderPrice(settlePrice);
        orderService.updateById(orderEntity);
        bookRQResult.setOrderId(ordId.toString());
        return XmlUtils.toXML(bookRQResult);
    }

    /**
     * 取消订单
     * @param orderEntity
     * @param userName
     * @return
     */
    public String cancel(OrderEntity orderEntity,String userName) {
        DtOrderChannelsEntity dtOrderChannelsEntity =  dtOrderChannelsService.sqlSelectKey(Constant.Channel.Mt.getValue(),userName);
        String accessKey = "";
        String secretKey = "";
        Integer partId = 0;
        if(dtOrderChannelsEntity != null) {
            accessKey = dtOrderChannelsEntity.getAccessKey();
            secretKey = dtOrderChannelsEntity.getSecretKey();
            partId = dtOrderChannelsEntity.getSid();
        }else {
            log.error("美团：请配置飞猪接口用户名为{}的店铺对应的美团渠道账号", userName);
        }
        CancelRQResult cancelRQResult = new CancelRQResult();
        CancelRequest cancelRequest = new CancelRequest();
        cancelRequest.setDistributorOrderId(orderEntity.getOrderCode().toString());
        if(orderEntity.getBuyOrderId() != null){
            cancelRequest.setMtOrderId(Long.valueOf(orderEntity.getBuyOrderId()));
            cancelRequest.setCancelReason("正常取消");
            cancelRequest.setCancelCheck(0);

            FxBaseApiRequest fxBaseApiRequest = new FxBaseApiRequest();
            fxBaseApiRequest.setAccesskey(accessKey);
            fxBaseApiRequest.setSecretKey(secretKey);
            fxBaseApiRequest.setPartnerId(partId);
            fxBaseApiRequest.setMethod("hotel.order.cancel");
            fxBaseApiRequest.setData(JSONObject.toJSONString(cancelRequest));
            String cancelResult = "";
            log.info("美团：取消订单，订单号：{},请求报文：{}", orderEntity.getOrderCode(), fxBaseApiRequest.getData());
            try{
                cancelResult = MtClient.post(fxBaseApiRequest);
            }catch (Exception ex){
                orderEntity.setOrderStatus(Constant.LocalOrderStatus.ApplyRefund.getValue());
                orderEntity.setBuyStatus(Constant.LocalOrdBuyStatus.ChargebackFail.getValue());
                log.error("美团：取消订单失败，订单号：{}，错误信息:{}",orderEntity.getOrderCode(),ex.toString());
            }
            log.info("美团：取消订单，订单号：{},返回报文：{}", orderEntity.getOrderCode(), cancelResult);
            CancelResponse cancelResponse = JSONObject.parseObject(cancelResult, CancelResponse.class);
            //成功取消
            if(cancelResponse.getCode() == 0){
                orderEntity.setOrderStatus(Constant.LocalOrderStatus.Refund.getValue());
                cancelRQResult.setOrderId(orderEntity.getOrderCode().toString());
            }else {
                orderEntity.setOrderStatus(Constant.LocalOrderStatus.ApplyRefund.getValue());
                orderEntity.setBuyStatus(Constant.LocalOrdBuyStatus.ChargebackFail.getValue());
            }
        }else { //如何下单还未成功，美团订单号还未生成，转人工
            orderEntity.setOrderStatus(Constant.LocalOrderStatus.ApplyRefund.getValue());
            orderEntity.setBuyStatus(Constant.LocalOrdBuyStatus.ChargebackFail.getValue());
        }
        cancelRQResult.setMessage("成功");
        cancelRQResult.setResultCode("0");
        cancelRQResult.setOrderId(orderEntity.getId().toString());
        //更新采购信息
        orderService.updateById(orderEntity);
        return XmlUtils.toXML(cancelRQResult);
    }

    /**
     * 前端下单
     * @param manuBookRQ
     */
    public R manuBooking(ManuBookRQ manuBookRQ) {
        R r = null;
        String orderCode = manuBookRQ.getOrderCode().toString();
        DtOrderChannelsEntity chanel = dtOrderChannelsService.sqlSelectByOrderId(Constant.Channel.Mt.getValue(), orderCode);
        if (chanel == null) {
            log.error("配置错误：请配置店铺对应的美团渠道");
            return R.error("配置错误：请配置店铺对应的美团渠道");
        }
        String accessKey = "";
        String secretKey = "";
        Integer partnerId = 0;
        Integer commRate = 0;

        accessKey = chanel.getAccessKey();
        secretKey = chanel.getSecretKey();
        partnerId = chanel.getSid();
        commRate = chanel.getCommRate();
        MtBook mtBook = new MtBook();
        mtBook.setHotelId(manuBookRQ.getHotelCode());
        mtBook.setGoodsId(manuBookRQ.getRateplanCode());
        String personNames = "";
        for (OrderGuest guest : manuBookRQ.getOrderGuests()) {
            personNames += guest.getName() + ",";
        }
        personNames = personNames.replaceAll("\\,$", "");
        mtBook.setPersonNames(personNames);
        mtBook.setContactName(manuBookRQ.getName());
        mtBook.setContactPhone(manuBookRQ.getPhone());
        mtBook.setArriveDate(DateUtils.format(manuBookRQ.getEarliestTime(), "yyyy-MM-dd HH:mm:ss"));
        mtBook.setCheckinDate(DateUtils.format(manuBookRQ.getCheckInDate(), "yyyy-MM-dd"));
        mtBook.setCheckoutDate(DateUtils.format(manuBookRQ.getCheckOutDate(), "yyyy-MM-dd"));
        mtBook.setRoomNum(Integer.valueOf(manuBookRQ.getRoomNum()));
        Integer totaolPrice = 0;
        Integer settlePrice = 0;
        //订单总价，单位为分。总价=预订房间数x预定日期内房间单价。
        // 例如，4月1日入住，4月3日离店，预定2间房，则总价=2*(4月1日房价+4月2日房价）
        List<Dailyroom> dailyrooms = manuBookRQ.getDailyRooms();
        for (Dailyroom d : dailyrooms) {
            totaolPrice += d.getPrice();
            settlePrice += d.getSubRatio() == null || d.getSubRatio() == 0 ? d.getPrice() * commRate : d.getPrice() * d.getSubRatio();
        }
        totaolPrice = totaolPrice * Integer.valueOf(manuBookRQ.getRoomNum());
        settlePrice = settlePrice * Integer.valueOf(manuBookRQ.getRoomNum()) / 1000;
        //结算价，单位为分。结算价=总价 - 分销商佣金。
        settlePrice = totaolPrice - settlePrice;
        mtBook.setTotalPrice(totaolPrice);
        mtBook.setSettlePrice(settlePrice);
        mtBook.setDistributorOrderId(orderCode);
        if (StringUtils.isNotBlank(manuBookRQ.getNote())) {
            mtBook.setComment(manuBookRQ.getNote());
        }
        //设置发票信息，目前都是酒店前台开票,不需要美团开票
        mtBook.setNeedInvoice(0);
        FxBaseApiRequest fxBaseApiRequest = new FxBaseApiRequest();
        fxBaseApiRequest.setAccesskey(accessKey);
        fxBaseApiRequest.setSecretKey(secretKey);
        fxBaseApiRequest.setPartnerId(partnerId);
        fxBaseApiRequest.setData(JSONObject.toJSONString(mtBook));
        fxBaseApiRequest.setMethod("hotel.order.booking");
        //更新采购信息
        OrderEntity orderEntity = new OrderEntity();
        //构造返回
        BookRQResult bookRQResult = new BookRQResult();
        String buyResult = "";
        log.info("美团：手工下单，订单号：{},请求报文：{}", manuBookRQ.getOrderCode(), fxBaseApiRequest.getData());
        try {
            buyResult = MtClient.post(fxBaseApiRequest);
        } catch (Exception ex) {
            orderEntity.setBuyStatus(0);
            orderEntity.setResultDesc(ex.toString().substring(0, 499));
            log.error("美团：手工下单失败，订单号：{}，错误信息：{}", orderCode, ex.toString());
            r = R.error("美团：手工下单失败：" + ex.toString());
        }
        log.info("美团：手工下单，订单号：{},返回报文：{}", manuBookRQ.getOrderCode(), buyResult);
        MtBookResult mtBookResult = JSONObject.parseObject(buyResult, MtBookResult.class);
        if (mtBookResult.getCode() == 0) {
            orderEntity.setBuyStatus(Constant.LocalOrdBuyStatus.Purchased.getValue());
            if (mtBookResult.getResult() != null && mtBookResult.getResult().getMtOrderId() != null) {
                orderEntity.setBuyOrderId(mtBookResult.getResult().getMtOrderId());
            }
            r = R.ok();
        } else {
            orderEntity.setBuyStatus(Constant.LocalOrdBuyStatus.Purchfailure.getValue());
            log.error("美团：预约下单失败，订单号:{}，错误信息：{}", mtBookResult.getMessage(), orderCode);
            r = R.error(buyResult);
        }
        orderEntity.setId(manuBookRQ.getId());
        orderEntity.setBuyOrderPrice(settlePrice);
        orderService.updateById(orderEntity);
        bookRQResult.setOrderId(orderCode);
        return r;
    }
}
